<template>
  <div class="header">
    <ul>
      <li>
        <Icon style="width: 25px; height: 25px" />
      </li>
      <!-- <li>
        <a-tooltip style="width: 20px; height: 20px">
          <template slot="title"> 撤销(Ctrl + Z) </template>
          <Chexiao @click="undoHandle" />
        </a-tooltip>
      </li>
      <li>
        <a-tooltip style="width: 20px; height: 20px">
          <template slot="title"> 重做(Ctrl + Y) </template>
          <Chenzuo @click="redoHandle" />
        </a-tooltip>
      </li> -->
      <li>
        <a-tooltip style="width: 20px; height: 20px">
          <template slot="title"> 删除 </template>
          <Delete @click="deleteHandle" />
        </a-tooltip>
      </li>
      <li>
        <a-tooltip style="width: 20px; height: 20px">
          <template slot="title"> 运行 </template>
          <Run @click="runHandle" />
        </a-tooltip>
      </li>
      <li>
        <div style="position: relative; top: -5px; left: 0px;">
          仿真时间:
          <a-input-number id="inputNumber" v-model="time" :min="0" :max="1000000" />
        </div>
      </li>
      <li>
        <div style="position: relative; top: -5px; left: 0px;">
          仿真步长:
          <a-input-number id="inputNumber" v-model="step" :min="0" :max="1000000" />
        </div>
      </li>
    </ul>
    <b>仿真建模</b>
    <div>
      <a-modal v-model="visible" title="仿真结果" :footer="null">
        <div style="white-space: pre-line;">
          {{ content }}
        </div>
      </a-modal>
    </div>
  </div>
</template>

<script>
import Icon from "@/assets/icon.svg";
import XinJian from "@/assets/xinjian.svg";
import Dakai from "@/assets/dakai.svg";
import Baocun from "@/assets/baocun.svg";
import Gengduo from "@/assets/gengduo.svg";
import Chexiao from "@/assets/chexiao.svg";
import Chenzuo from "@/assets/chenzuo.svg";
import Run from "@/assets/run.svg";
import Delete from "@/assets/delete.svg";

import utils from "@/utils/utils";
import { localApi } from "@/api/main";
import { VUEREF } from '@/store/mutation-types';

export default {
  components: {
    Icon,
    XinJian,
    Dakai,
    Baocun,
    Gengduo,
    Chexiao,
    Chenzuo,
    Run,
    Delete,
  },

  data() {
    return {
      visible: false,
      content: "test...",
      time: 1,
      step: 1,
      sample: 1000,
      isRun: false,
    };
  },

  mounted() {
    document.addEventListener('keydown', this.handleKeyDown);
  },
  beforeDestroy() {
    document.removeEventListener('keydown', this.handleKeyDown);
  },

  methods: {
    getMockData() {
      let mockData = {
        nodes: [],
        edges: [],
      };
      let data = this.$store.state.model.canvansRef.getDataMap();
      for (let i = 0; i < data.nodes.length; i++) {
        const element = data.nodes[i];
        let node = {};
        node.id = element.id;
        node.index = element.options.nodeData.index;
        node.top = element.top;
        node.left = element.left;
        node.name = element.options.nodeData.name;
        node.dllFile = element.options.nodeData.dllFile;
        node.fctName = element.options.nodeData.fctName;
        node.params = element.options.nodeData.params;
        mockData.nodes.push(node);
      }
      for (let i = 0; i < data.edges.length; i++) {
        const element = data.edges[i];
        let edge = {};
        edge.id = element.id;
        edge.sourceNode = element.sourceNode.id;
        edge.targetNode = element.targetNode.id;
        edge.source = element.sourceEndpoint.id;
        edge.target = element.targetEndpoint.id;
        mockData.edges.push(edge);
      }
      return mockData;
    },

    undoHandle() {
      this.$store.state.model.canvansRef.undo();
    },

    redoHandle() {
      this.$store.state.model.canvansRef.redo();
    },

    clearHandle() {
      localStorage.removeItem("mockData");
      console.log("clear mockdata!");
    },

    deleteHandle() {
      let canvans = this.$store.state.model.canvansRef;
      let nodeId = this.$store.state.model.attrForm.default.id;
      if (canvans && nodeId) {
        canvans.removeNode(nodeId);
        this.$store.state.model.vueRef[VUEREF.BUTTERFLY].deleteNode(nodeId);
      }
    },

    handleKeyDown(event) {
      if (event.key === 'Delete') {
        this.deleteHandle();
      }
    },

    startRun(parameter) {
      return new Promise(function (resolve, reject) {
        localApi("startRun", parameter).then((ret) => {
          resolve(ret);
        });
      });
    },

    stepRun(stepParam) {
      let self = this;
      return new Promise(function (resolve, reject) {
        localApi("stepRun", stepParam).then((ret) => {
          for (let i = 0; i < ret.data.length; i++) {
            let element = ret.data[i];
            element.params[0].value = element.outvalue.toFixed(6);
            let form = {
              id: element.id,
              name: element.name,
              params: element.params
            }
            self.$store.dispatch("model/setAttrForm", { key: element.id, form: form });
            if (self.$store.state.model.attrForm.default.id == element.id) {
              self.$store.dispatch("model/setAttrForm", { key: 'default', form: form });
            }
          }
          resolve(true);
        });
      });
    },

    async runHandle() {
      if (this.isRun) {
        this.isRun = false;
        this.$store.dispatch("model/addLog", `${new Date().toLocaleString()} 停止仿真`);
        return;
      }

      this.$store.dispatch("model/clearLog");
      let mockData = this.getMockData();
      if (mockData.nodes.length <= 0) {
        this.$store.dispatch("model/addLog", `${new Date().toLocaleString()} 空画板`);
        return;
      }

      this.$store.dispatch("model/addLog", `${new Date().toLocaleString()} 开始仿真`);
      let parameter = {
        step_size: this.step,
        mockData: mockData
      }
      let ret = await this.startRun(parameter);
      if (ret.data.code !== 0) {
        this.$store.dispatch("model/addLog", `${new Date().toLocaleString()} 存在环，请添加延时标记模块!`);
        return;
      }

      // 排序打印
      let sortStr = '';
      for (let i = 0; i < ret.data.sortInfo.length; i++) {
        const element = ret.data.sortInfo[i];
        sortStr = sortStr + element.fctName + '->';
      }
      sortStr = '排序：' + sortStr + 'end';
      this.$store.dispatch("model/addLog", `${new Date().toLocaleString()} ${sortStr}`);

      // 开始执行仿真
      this.isRun = true;
      let totalStep = Math.ceil(this.time / this.step);
      let totalTime = this.time;
      let realTime = Date.now();
      let norCount = Math.floor(totalStep / this.sample);
      let modCount = totalStep % this.sample;

      for (let i = 0; i < norCount; i++) {
        if (!this.isRun) {
          break;
        }
        await this.stepRun({
          sample: this.sample,
          sortInfo: ret.data.sortInfo
        });
      }

      if (this.isRun) {
        if (modCount > 0) {
          await this.stepRun({
            sample: modCount,
            sortInfo: ret.data.sortInfo
          });
        }
        realTime = (Date.now() - realTime) / 1000;
        this.$store.dispatch("model/addLog", `${new Date().toLocaleString()} 仿真引擎运行结束, 共运行${totalStep}步, ${totalTime}秒, 实际耗时${realTime}秒`);
      }
      this.isRun = false;
    },
  },
};
</script>

<style scoped>
ul {
  width: 800px;
  height: 35px;
  line-height: 35px;
  list-style-type: none;
  float: left;
  position: absolute;
  left: -40px;
}

li {
  float: left;
  padding: 5px 10px;
}
</style>